#include <linux/module.h>
#include <linux/init.h>

#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/platform_device.h>

#include <asm/io.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zl");

int zl_probe(struct device * dev)
{
    struct platform_device *pdev = container_of(dev, struct platform_device, dev);
    struct resource *res = pdev->resource;

    printk("[%s %d ]\n", __FUNCTION__, __LINE__);

    return 0;
}

int zl_remove(struct device * dev)
{
    printk("[%s %d ]\n", __FUNCTION__, __LINE__);
    return 0;
}

struct device_driver zl_driver_struct = {
    .name = "zl_device",
    .bus = &platform_bus_type,
    .probe = zl_probe,
    .remove = zl_remove,
};

void zl_release(struct device *dev)
{
    printk("[%s %d ]\n", __FUNCTION__, __LINE__);
}

struct resource zl_res[] = {
    {
        .name  = "zl_res_name",
        .start = 0x56000000,
        .end   = 0x57000000,
        .flags = IORESOURCE_IO,
    },

    {
        .start = IRQ_EINT2,
        .end   = IRQ_EINT2,
        .flags = IORESOURCE_IRQ,
    },
};

struct platform_device zl_dev = {
    .name = "zl_device",  /* this string will be shown as /sys/devices/platform/zl_device.0 */
    .dev = {
        .release = zl_release,
    },
    .num_resources = ARRAY_SIZE(zl_res),
    .resource = zl_res,
};

int dev_init(void)
{
    int ret = 0;

    ret = platform_device_register(&zl_dev);
    ret = driver_register(&zl_driver_struct);

    printk("[%s %d ]\n", __FUNCTION__, __LINE__);

    return ret;
}

void dev_exit(void)
{
    driver_unregister(&zl_driver_struct);
    platform_device_unregister(&zl_dev);

    printk("[%s %d ]\n", __FUNCTION__, __LINE__);
}

module_init(dev_init);
module_exit(dev_exit);

// http://blogold.chinaunix.net/u4/120285/showart_2549503.html
